00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef _complex_operators_hpp_
00028 #define _complex_operators_hpp_
00029
00030 #include <functional>
00031 #include <algorithm>
00032
00033 #include <boost/static_assert.hpp>
00034 #include <boost/type_traits/is_same.hpp>
00035 #include "gridpack/utilities/complex.hpp"
00036
00037 namespace gridpack {
00038 namespace math {
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 template <typename To, typename From>
00052 inline To
00053 equate(const From& f)
00054 {
00055 To t;
00056 t = f;
00057 return t;
00058 }
00059
00060 template <>
00061 inline RealType
00062 equate<RealType, ComplexType>(const ComplexType& f)
00063 {
00064 RealType t;
00065 t = std::real(f);
00066 return t;
00067 }
00068
00069
00070
00071
00072 template <typename T>
00073 struct base_unary_function : public std::unary_function<T, T>
00074 {
00075 virtual T operator() (const T& t) const = 0;
00076 };
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 template <typename T, typename StorageType>
00094 inline void
00095 unary_operation(const unsigned int& size, StorageType *x,
00096 base_unary_function<T>& op)
00097 {
00098 for (unsigned int i = 0; i < size; ++i) {
00099 x[i] = op(x[i]);
00100 }
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 template <>
00117 inline void
00118 unary_operation<ComplexType, RealType>(const unsigned int& size, RealType *x,
00119 base_unary_function<ComplexType>& op)
00120 {
00121 for (unsigned int i = 0; i < size; i += 2) {
00122 ComplexType tmp(x[i], x[i+1]);
00123 tmp = op(tmp);
00124 x[i] = std::real(tmp);
00125 x[i+1] = std::imag(tmp);
00126 }
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 template <>
00140 inline void
00141 unary_operation<RealType, ComplexType>(const unsigned int& size, ComplexType *x,
00142 base_unary_function<RealType>& op)
00143 {
00144 for (unsigned int i = 0; i < size; ++i) {
00145 RealType tmp(std::real(x[i]));
00146 x[i] = op(tmp);
00147 }
00148 }
00149
00150
00151
00152
00153 template <typename T>
00154 struct setvalue : public base_unary_function<T>
00155 {
00156 const T value;
00157 setvalue(const T& v) : value(v) {}
00158 T operator() (const T& x) const { return value; }
00159 };
00160
00161
00162
00163
00164 template <typename T>
00165 struct addvalue : public base_unary_function<T>
00166 {
00167 const T value;
00168 addvalue(const T& v) : value(v) {}
00169 T operator() (const T& x) const { return x+value; }
00170 };
00171
00172
00173
00174
00175
00176 template <typename T>
00177 struct multiplyvalue : public base_unary_function<T>
00178 {
00179 const T factor;
00180 multiplyvalue(const T& f) : factor(f) {}
00181 T operator() (const T& x) const { return x*factor; }
00182 };
00183
00184
00185
00186
00187 template <typename T>
00188 struct absvalue : public base_unary_function<T>
00189 {
00190 T operator() (const T& x) const {
00191 return x;
00192 }
00193 };
00194
00195 template <>
00196 struct absvalue<RealType> : public base_unary_function<RealType>
00197 {
00198 RealType operator() (const RealType& x) const {
00199 return fabs(x);
00200 }
00201 };
00202
00203 template <>
00204 struct absvalue<ComplexType> : public base_unary_function<ComplexType>
00205 {
00206 ComplexType operator() (const ComplexType& x) const {
00207 return std::abs(x);
00208 }
00209 };
00210
00211
00212
00213
00214 template <typename T>
00215 struct exponential : public base_unary_function<T>
00216 {
00217 T operator() (const T& x) const { return exp(x); }
00218 };
00219
00220
00221
00222
00223 template <typename T>
00224 struct reciprocal : public base_unary_function<T>
00225 {
00226 T operator() (const T& x) const {
00227 T one(1.0);
00228 return one/x;
00229 }
00230 };
00231
00232
00233
00234
00235 template <typename T>
00236 struct conjugate_value : public base_unary_function<T>
00237 {
00238 inline T operator() (const T& x) const;
00239 };
00240
00241 template <>
00242 inline RealType
00243 conjugate_value<RealType>::operator() (const RealType& x) const
00244 {
00245 return x;
00246 }
00247
00248 template <>
00249 inline ComplexType
00250 conjugate_value<ComplexType>::operator() (const ComplexType& x) const
00251 {
00252 return std::conj(x);
00253 }
00254
00255
00256
00257
00258 template <typename T>
00259 struct real_value : public base_unary_function<T>
00260 {
00261 inline T operator() (const T& x) const;
00262 };
00263
00264 template <>
00265 inline RealType
00266 real_value<RealType>::operator() (const RealType& x) const
00267 {
00268 return x;
00269 }
00270
00271 template <>
00272 inline ComplexType
00273 real_value<ComplexType>::operator() (const ComplexType& x) const
00274 {
00275 return std::real(x);
00276 }
00277
00278
00279
00280
00281 template <typename T>
00282 struct imaginary_value : public base_unary_function<T>
00283 {
00284 inline T operator() (const T& x) const;
00285 };
00286
00287 template <>
00288 inline RealType
00289 imaginary_value<RealType>::operator() (const RealType& x) const
00290 {
00291 return 0.0;
00292 }
00293
00294 template <>
00295 inline ComplexType
00296 imaginary_value<ComplexType>::operator() (const ComplexType& x) const
00297 {
00298 return std::imag(x);
00299 }
00300
00301
00302
00303
00304
00305 template <typename T, typename ResultType>
00306 struct base_accumulator_function : public std::unary_function<T, void>
00307 {
00308 ResultType accum;
00309 virtual void operator() (const T& t) = 0;
00310 virtual ResultType result(void) const
00311 {
00312 return accum;
00313 }
00314 base_accumulator_function(void)
00315 : std::unary_function<T, void>(), accum(0.0)
00316 {}
00317 };
00318
00319
00320
00321
00322
00323 template <typename T, typename StorageType>
00324 inline void
00325 accumulator_operation(const unsigned int& size, const StorageType *x,
00326 base_accumulator_function<T, RealType>& op)
00327 {
00328 for (unsigned int i = 0; i < size; ++i) {
00329 op(x[i]);
00330 }
00331 }
00332
00333 template <>
00334 inline void
00335 accumulator_operation<RealType, ComplexType>(const unsigned int& size,
00336 const ComplexType *x,
00337 base_accumulator_function<RealType, RealType>& op)
00338 {
00339 for (unsigned int i = 0; i < size; i += 1) {
00340 RealType tmp(real(x[i]));
00341 op(tmp);
00342 }
00343 }
00344
00345 template <>
00346 inline void
00347 accumulator_operation<ComplexType, RealType>(const unsigned int& size,
00348 const RealType *x,
00349 base_accumulator_function<ComplexType, RealType>& op)
00350 {
00351 for (unsigned int i = 0; i < size; i += 2) {
00352 ComplexType tmp(x[i], x[i+1]);
00353 op(tmp);
00354 }
00355 }
00356
00357
00358
00359
00360
00361 template <typename T>
00362 struct l1_norm : public base_accumulator_function<T, RealType>
00363 {
00364 inline void operator() (const T& t);
00365 };
00366
00367 template <>
00368 inline void
00369 l1_norm<RealType>::operator() (const RealType& x)
00370 {
00371 accum += ::fabs(x);
00372 }
00373
00374 template <>
00375 inline void
00376 l1_norm<ComplexType>::operator() (const ComplexType& x)
00377 {
00378 accum += std::abs(x);
00379 }
00380
00381
00382
00383
00384 template <typename T>
00385 struct l2_norm : public base_accumulator_function<T, RealType>
00386 {
00387 inline void operator() (const T& x);
00388 };
00389
00390 template <>
00391 inline void
00392 l2_norm<RealType>::operator() (const RealType& x)
00393 {
00394 accum += x*x;
00395 }
00396
00397 template <>
00398 inline void
00399 l2_norm<ComplexType>::operator() (const ComplexType& x)
00400 {
00401 RealType rx(std::abs(x));
00402 accum += rx*rx;
00403 }
00404
00405
00406
00407
00408 template <typename T>
00409 struct infinity_norm : public base_accumulator_function<T, RealType>
00410 {
00411 inline void operator() (const T& x);
00412 };
00413
00414 template <>
00415 inline void
00416 infinity_norm<RealType>::operator() (const RealType& x)
00417 {
00418
00419 accum = std::max(accum, ::fabs(x));
00420 }
00421
00422 template <>
00423 inline void
00424 infinity_norm<ComplexType>::operator() (const ComplexType& x)
00425 {
00426
00427 accum = std::max(accum, std::abs(x));
00428 }
00429
00430
00431
00432
00433
00434 template <typename T>
00435 struct base_binary_function : public std::binary_function<T, T, T>
00436 {
00437 virtual T operator() (const T& x1, const T& x2) const = 0;
00438 };
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 template <typename T, typename StorageType>
00458 inline void
00459 binary_operation(const unsigned int& size,
00460 StorageType *x1, const StorageType *x2,
00461 base_binary_function<T>& op)
00462 {
00463 for (unsigned int i = 0; i < size; i += 1) {
00464 T result = op(x1[i], x2[i]);
00465 x1[i] = result;
00466 }
00467 }
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 template <>
00488 inline void
00489 binary_operation<ComplexType, RealType>(const unsigned int& size,
00490 RealType *x1, const RealType *x2,
00491 base_binary_function<ComplexType>& op)
00492 {
00493 for (unsigned int i = 0; i < size; i += 2) {
00494 ComplexType tmp1(x1[i], x1[i+1]);
00495 ComplexType tmp2(x2[i], x2[i+1]);
00496 ComplexType result(op(tmp1, tmp2));
00497 x1[i] = std::real(result);
00498 x1[i+1] = std::imag(result);
00499 }
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 template <>
00516 inline void
00517 binary_operation<RealType, ComplexType>(const unsigned int& size,
00518 ComplexType *x1, const ComplexType *x2,
00519 base_binary_function<RealType>& op)
00520 {
00521 for (unsigned int i = 0; i < size; ++i) {
00522 RealType tmp1(std::real(x1[i]));
00523 RealType tmp2(std::real(x2[i]));
00524 RealType result(op(tmp1, tmp2));
00525 x1[i] = result;
00526 }
00527 }
00528
00529
00530
00531
00532 template <typename T>
00533 struct multiplyvalue2 : public base_binary_function<T>
00534 {
00535 T operator() (const T& x1, const T& x2) const { return x1*x2; }
00536 };
00537
00538
00539
00540
00541 template <typename T>
00542 struct dividevalue2 : public base_binary_function<T>
00543 {
00544 T operator() (const T& x1, const T& x2) const { return x1/x2; }
00545 };
00546
00547
00548
00549
00550 template <typename T>
00551 struct scaleAdd2 : public base_binary_function<T>
00552 {
00553 T alpha;
00554 T operator() (const T& x1, const T& x2) const { return x1 + alpha*x2; }
00555 scaleAdd2(const T& a = 1.0)
00556 : base_binary_function<T>(), alpha(a)
00557 {}
00558 };
00559
00560
00561 }
00562 }
00563 #endif